#ifndef PROTOCAL_HPP
#define PROTOCAL_HPP

// 你的代码


#include <iostream>
#include <jsoncpp/json/json.h>
#include <memory>
#include <string>

const std::string stmp = "\r\n";
// 我的目的是生成123"/r/n"std::st"/r/n"这样的长串

// 加报头
bool Encode(std::string &packge) // packge报文
{
    if (packge.size() == 0)
        return false;
    std::string message = std::to_string(packge.size()) + stmp + packge + stmp;
    packge = message;
    return true;
}

// 去报头
// 123"/r/n"std::st"/r/n"
// 123"/r/n"std::st"/r/n"127"/r/n"
// 123"/r/n"

bool Decode(std::string &packge, std::string *content)
{
    // 判断报文是否是大于等于一个整报文的长度
    // 1.先获得报头中的报文长度字段
    auto pos = packge.find(stmp);
    if (pos == std::string::npos)
        return false;
    std::string content_length_str = packge.substr(0, pos);
    int content_length = std::stoi(content_length_str); // 报文正文部分长度
    // 2.利用关系，来确定是否获得的是至少完整的报文
    int full_content_length = content_length_str.size() + content_length + 2 * stmp.size();
    if (packge.size() < full_content_length)
        return false;
    *content = packge.substr(pos+stmp.size(),content_length);
    packge.erase(0,full_content_length);
    return true;
}

// 客户端发送，我构建一个req
class request
{
public:
    request() : _x(0), _y(0), _oper(0)
    {
    }
    request(int x, int y, char oper) : _x(x), _y(y), _oper(oper)
    {
    }
    // 进行序列化
    bool Serialize(std::string &out_string)
    {
        Json::Value root;
        root["x"] = _x; // 键值对，键是用来帮助序列化和反序列化做参照的，值是每个成员变量的值
        root["y"] = _y;
        root["oper"] = _oper;

        // 创造工厂
        Json::StreamWriterBuilder WriterBuilder;
        std::unique_ptr<Json::StreamWriter> Writer(WriterBuilder.newStreamWriter());
        std::stringstream ss;
        Writer->write(root, &ss);
        out_string = ss.str();
        return true;
    }

    void Print()
    {
        std::cout << _x << std::endl;
        std::cout << _oper << std::endl;
        std::cout << _y << std::endl;
    }

    bool Deserialize(std::string out_string)
    {
        Json::Value root;
        Json::Reader read;

        bool ParseSuccessful = read.parse(out_string, root);
        if (!ParseSuccessful)
        {
            std::cerr << "Failed Parse" << read.getFormatedErrorMessages() << std::endl;
            return false;
        }
        _x = root["x"].asInt();
        _y = root["y"].asInt();
        _oper = root["oper"].asInt();
        return true;
    }

    int X()const
    {
        return _x;
    }

    int Y()const
    {
        return _y;
    }

    int Oper()const
    {
        return _oper;
    }

    ~request()
    {
    }

private:
    int _x;
    int _y;
    char _oper;
};

class response
{
public:
    response() : _result(0), _code(0)
    {
    }

    // 进行序列化
    bool Serialize(std::string &out_string)
    {
        Json::Value root;
        root["result"] = _result; // 键值对，键是用来帮助序列化和反序列化做参照的，值是每个成员变量的值
        root["code"] = _code;

        // 创造工厂
        Json::StreamWriterBuilder WriterBuilder;
        std::unique_ptr<Json::StreamWriter> Writer(WriterBuilder.newStreamWriter());
        std::stringstream ss;
        Writer->write(root, &ss);
        out_string = ss.str();
        return true;
    }

    bool Deserialize(std::string out_string)
    {
        Json::Value root;
        Json::Reader read;

        bool ParseSuccessful = read.parse(out_string, root);
        if (!ParseSuccessful)
        {
            std::cerr << "Failed Parse" << read.getFormatedErrorMessages() << std::endl;
            return false;
        }
        _result = root["result"].asInt();
        _code = root["code"].asInt();
        return true;
    }

    void Setresult(int result)
    {
        _result = result;
    }

    void Setcode(int code)
    {
        _code = code;
    }

    int result()
    {
        return _result;
    }

    int code()
    {
        return _code;
    }

    ~response()
    {
    }
    int _result;
    int _code; // 错误码   0为正常 1为除0 2为模0
};

#endif 